<template>
  <div v-loading="queueLoading" class="product-card-container">
    <div class="header">
      <div v-for="item in headers" class="item">
        <component v-if="!!item.icon" :is="item.icon" />
        <span>{{ item.title }}</span>
        <el-divider direction="vertical" />
        <span>{{ item.value }}</span>
      </div>
    </div>
    <div class="content">
      <el-scrollbar ref="scrollRef" @scroll="handleScroll">
        <merak-collapse v-model="collapseActive">
          <template v-for="(block, blockKey) in blocks">
            <merak-collapse-item v-if="block.visible" :name="blockKey" :title="block.title" hideMarker>
              <template v-if="![BlockKeys.image, BlockKeys.video].includes(blockKey)" #handler>
                <template v-if="blockEdits[blockKey]">
                  <el-button @click="handleCancel(blockKey)">{{ $t("merak.cancel") }}</el-button>
                  <el-button type="primary" :loading="blockSaveLoading[blockKey]" @click="handleSave(blockKey)">
                    {{ $t("merak.save") }}
                  </el-button>
                </template>
                <el-button
                  v-else-if="blockKey === BlockKeys.spec"
                  v-auth="{ authArr: auth, key: 'edit' }"
                  type="primary"
                  link
                  :icon="CirclePlus"
                  @click="blockRefs[BlockKeys.spec]?.handleAdd"
                >
                  {{ $t("goods_archive.add_new_art_no") }}
                </el-button>
                <el-button
                  v-else
                  v-auth="{ authArr: auth, key: 'edit' }"
                  type="primary"
                  link
                  :icon="Edit"
                  @click="handleEdit(blockKey)"
                >
                  {{ $t("merak.edit") }}
                </el-button>
              </template>
              <component
                v-bind="block.props"
                :ref="(el: any) => (blockRefs[blockKey] = el)"
                :is="block.component"
                :queueId="queueId"
                :span="span"
                :auth="auth"
                :config="config"
                :editor="blockEdits[blockKey]"
                :info="blockInfo[blockKey]"
                :data="blockData[blockKey]"
                :readonly="blockReadonly[blockKey]"
                :tableHeader="tableHeader"
                @play="handlePlayScroll"
                @freight="(id: string | number) => (topProductId = id)"
              />
            </merak-collapse-item>
          </template>
        </merak-collapse>
      </el-scrollbar>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { Component } from "vue";

import type { MerakControlProps } from "@/components/MerakControl";

import { BlockKeys, BlockRefs } from "./index";

import { h, getCurrentInstance, ref, reactive, computed, provide, onMounted } from "vue";

import { useRoute, useRouter } from "vue-router";

import useLoading from "@/hooks/useLoading";

import { useGlobalStore } from "@/stores/modules/global";

import { useTabsStore } from "@/stores/modules/tabs";

import { ElDivider, ElScrollbar, ElButton, ElMessage, ElMessageBox } from "element-plus";

import { Timer, User, Edit, CirclePlus } from "@element-plus/icons-vue";

import { MerakCollapse, MerakCollapseItem } from "@/components/MerakCollapse";

import Base from "./components/Base.vue";
import Spec from "./components/Spec.vue";
import Clear from "./components/Clear.vue";
import Sale from "./components/Sale.vue";
import ImageView from "./components/ImageView.vue";
import VideoView from "./components/VideoView.vue";

import { ResultEnum } from "@/enums/httpEnum";
import { InitParams, getInitData, saveEditData } from "@/api/modules/goodsArchive/addGoodsArchive";
import { UserAuthType, getUserAuth } from "@/api/modules/user";

import { confirmWarningMsg } from "@/utils/messageUtils";

const currentInstance = getCurrentInstance();

/**
 * 路由参数
 * @param typeId 品类 ID
 * @param productId 商品 ID
 * @param suite 是否套件
 */
const { query, fullPath, ...other } = useRoute();

const router = useRouter();

console.log(other, router);

const { queueId, queueLoading } = useLoading(1000);

const { language } = useGlobalStore();

const { removeTabs } = useTabsStore();

const scrollRef = ref<InstanceType<typeof ElScrollbar>>();

// 页面权限
const auth = ref<UserAuthType>({});

// 顶层商品ID
const topProductId = ref<string | number>();

// 数据操作者信息
const operator = ref<Record<string, any>>({});

/**
 * 页面配置数据
 * @param has_color 是否有颜色 0: 否  1: 是
 * @param has_size 是否有规格 0: 否  1: 是
 * @param has_gender 是否有性别 0: 否  1: 是
 * @param package_type 套装格式 0: 无  1: 单尺码  2: 多尺码
 * @param spec_type 规格 1: 文本  2: 枚举
 */
const config = ref<Record<string, any>>({});

const countdown = ref(5);

const tableHeader = reactive<Record<string, any>>({});

// 当前展开块
const collapseActive = reactive<BlockKeys[]>([
  BlockKeys.base,
  BlockKeys.spec,
  BlockKeys.clear,
  BlockKeys.sale,
  BlockKeys.image,
  BlockKeys.video
]);

// 块 ref 集合
const blockRefs = reactive<BlockRefs>({});

// 块编辑集合
const blockEdits = reactive<Record<BlockKeys, boolean>>({
  [BlockKeys.base]: false,
  [BlockKeys.spec]: false,
  [BlockKeys.clear]: false,
  [BlockKeys.sale]: false,
  [BlockKeys.image]: false,
  [BlockKeys.video]: false
});

// 块保存 loading 状态
const blockSaveLoading = reactive<Record<BlockKeys, boolean>>({
  [BlockKeys.base]: false,
  [BlockKeys.spec]: false,
  [BlockKeys.clear]: false,
  [BlockKeys.sale]: false,
  [BlockKeys.image]: false,
  [BlockKeys.video]: false
});

// 块渲染数据
const blockInfo = reactive<{
  [BlockKeys.base]: MerakControlProps[];
  [BlockKeys.spec]: Record<string, any>;
  [BlockKeys.clear]: MerakControlProps[];
  [BlockKeys.sale]: MerakControlProps[];
}>({
  [BlockKeys.base]: [],
  [BlockKeys.spec]: {},
  [BlockKeys.clear]: [],
  [BlockKeys.sale]: []
});

// 块表单数据
const blockData = reactive<{
  [BlockKeys.base]: Record<string, any>;
  [BlockKeys.spec]: Array<Record<string, any>>;
  [BlockKeys.clear]: Record<string, any>;
  [BlockKeys.sale]: Record<string, any>;
  [BlockKeys.image]: Record<string | number, any>;
  [BlockKeys.video]: Record<string, any>;
}>({
  [BlockKeys.base]: {},
  [BlockKeys.spec]: [],
  [BlockKeys.clear]: {},
  [BlockKeys.sale]: {},
  [BlockKeys.image]: {},
  [BlockKeys.video]: {}
});

// 块只读信息
const blockReadonly = reactive<{
  [BlockKeys.base]: Array<string>;
  [BlockKeys.spec]: Array<string>;
  [BlockKeys.clear]: Array<string>;
  [BlockKeys.sale]: Array<string>;
}>({
  [BlockKeys.base]: [],
  [BlockKeys.spec]: [],
  [BlockKeys.clear]: [],
  [BlockKeys.sale]: []
});

// 头部信息
const headers = computed(() => [
  { title: currentInstance?.proxy?.$t("merak.created_at"), value: operator.value?.created_at, icon: Timer },
  { title: currentInstance?.proxy?.$t("goods_archive.last_updated_at"), value: operator.value?.updated_at },
  { title: currentInstance?.proxy?.$t("merak.created_by"), value: operator.value?.created_by, icon: User },
  { title: currentInstance?.proxy?.$t("goods_archive.last_updated_by"), value: operator.value?.updated_by }
]);

// 表单动态列
const span = computed<number>(() => (language === "zh" ? 8 : 8));

// 展示块
const blocks = computed<
  Record<BlockKeys, { visible: boolean; title?: string; component: Component; props: Record<string, any> }>
>(() => ({
  [BlockKeys.base]: {
    visible: !!blockInfo[BlockKeys.base].length,
    title: currentInstance?.proxy?.$t("goods_archive.edit_base_info"),
    component: Base,
    props: {}
  },
  [BlockKeys.spec]: {
    visible: !!config.value.has_color || !!config.value.has_size,
    title: currentInstance?.proxy?.$t("goods_archive.art_no_info"),
    component: Spec,
    props: {}
  },
  [BlockKeys.clear]: {
    visible: !!blockInfo[BlockKeys.clear].length,
    title: currentInstance?.proxy?.$t("goods_archive.customs_clearance_attr"),
    component: Clear,
    props: {}
  },
  [BlockKeys.sale]: {
    visible: !!blockInfo[BlockKeys.sale].length,
    title: currentInstance?.proxy?.$t("goods_archive.sales_attr"),
    component: Sale,
    props: {}
  },
  [BlockKeys.image]: {
    visible: !!Object.values(blockData[BlockKeys.image]).length,
    title: currentInstance?.proxy?.$t("goods_archive.goods_picture"),
    component: ImageView,
    props: {}
  },
  [BlockKeys.video]: {
    visible: !!Object.keys(blockData[BlockKeys.video]).length,
    title: currentInstance?.proxy?.$t("goods_archive.goods_video"),
    component: VideoView,
    props: {}
  }
}));

// 取消按钮触发
const handleCancel = (key: BlockKeys) => {
  blockRefs[key]?.handleCancel?.()?.then(() => {
    blockEdits[key] = false;
  });
};

// 保存按钮触发
const handleSave = (key: BlockKeys) => {
  blockRefs[key]
    ?.handleSave?.()
    ?.then(value => {
      const formData: Record<string, any> = {};
      blockInfo[key].forEach((item: MerakControlProps) => {
        if (!blockReadonly[key].includes(item.field)) {
          formData[item.field] = value[item.field] ?? '';
        }
      });
      return Promise.resolve(formData);
    })
    .then(value => {
      const baseData = {
        type_id: query.t_id?.toString(),
        product_id: topProductId.value ?? query.p_id?.toString(),
        goods_id: query.g_id?.toString()
      };
      confirmWarningMsg({
        msg: currentInstance?.proxy?.$t("goods_archive.edit_goods_message") ?? "",
        callback: async (status: string) => {
          if (status === "confirm") {
            blockSaveLoading[key] = true;
            await saveEditData({ ...baseData, ...value }).then(({ code, message }) => {
              if (code == ResultEnum.SUCCESS) {
                blockEdits[key] = false;
                ElMessage.success(currentInstance?.proxy?.$t("goods_archive.edit_goods_success"));
              } else {
                const msg = typeof message === "object" ? Object.values(message)?.[0] : message;
                ElMessage.error(msg);
              }
            });
            blockSaveLoading[key] = false;
          }
        }
      });
    });
};

// 编辑按钮触发
const handleEdit = (key: BlockKeys) => {
  blockRefs[key]?.handleEdit?.()?.then(() => {
    blockEdits[key] = true;
  });
};

// 验证数据
const validValue = (value: any) => typeof value === "number" || !!value;

const handleScroll = () => {
  blockRefs[BlockKeys.base]?.closePanel();
  blockRefs[BlockKeys.clear]?.closePanel();
  blockRefs[BlockKeys.sale]?.closePanel();
};

const handlePlayScroll = () => {
  const timer = requestAnimationFrame(() => {
    scrollRef.value?.setScrollTop(99999);
    cancelAnimationFrame(timer);
  });
};

const init = () => {
  // 初始化
  const params: InitParams = {
    type_id: query.t_id?.toString(),
    goods_id: query.g_id?.toString(),
    product_id: topProductId.value ?? query.p_id?.toString(),
    is_suite: query.s_id == "1" ? 1 : 0,
    is_copy: 0
  };
  getInitData(params, queueId.value).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      operator.value = { ...(data.form_value?.operator ?? {}) };
      config.value = { ...(data.config ?? {}) };
      Object.assign(tableHeader, { ...(data.form_value?.spec_title ?? {}) });
      // 渲染数据填充
      Object.assign(blockInfo, {
        [BlockKeys.base]: [...(data.info ?? [])],
        [BlockKeys.spec]: { ...(data.spec ?? {}) },
        [BlockKeys.clear]: [...(data.cc_info ?? [])],
        [BlockKeys.sale]: [...(data.qf_info ?? [])]
      });
      // 回显数据填充
      Object.assign(blockData, {
        [BlockKeys.base]: { ...(data.form_value?.info ?? {}) },
        [BlockKeys.spec]: [...(data.form_value?.spec ?? [])],
        [BlockKeys.clear]: { ...(data.form_value?.cc_info ?? {}) },
        [BlockKeys.sale]: { ...(data.form_value?.qf_info ?? {}) },
        [BlockKeys.image]: { ...(data.form_value?.images ?? {}) },
        [BlockKeys.video]: { ...(data.form_value?.video ?? {}) }
      });
      // 只读字段填充
      Object.assign(blockReadonly, {
        [BlockKeys.base]: [...(data.form_readonly?.info ?? [])],
        [BlockKeys.spec]: [...(data.form_readonly?.spec ?? [])],
        [BlockKeys.clear]: [...(data.form_readonly?.cc_info ?? [])],
        [BlockKeys.sale]: [...(data.form_readonly?.qf_info ?? [])]
      });
    } else if (code === 3000) {
      const { product_id } = data;
      if (!!product_id) {
        // topProductId.value = product_id;
        // init();
        router.replace({ name: other.name ?? "", query: { ...query, p_id: product_id } });
      }
    } else {
      const timer = setInterval(() => {
        if (countdown.value <= 1) {
          ElMessageBox.close();
          clearInterval(timer);
          removeTabs(fullPath);
          return;
        }
        countdown.value--;
      }, 1000);
      ElMessageBox({
        type: "warning",
        title: currentInstance?.proxy?.$t("merak.tip_modal"),
        message: () =>
          h(
            "p",
            null,
            `${currentInstance?.proxy?.$t("goods_archive.delete_product_tip_one")} ${
              countdown.value
            } ${currentInstance?.proxy?.$t("goods_archive.delete_product_tip_two")}`
          ),
        showClose: false,
        showCancelButton: false,
        closeOnClickModal: false,
        closeOnPressEscape: false,
        confirmButtonText: currentInstance?.proxy?.$t("goods_archive.close_page")
      }).then(() => {
        clearInterval(timer);
        removeTabs(fullPath);
        router.back();
      });
    }
  });
};

// 注入页面 refs 集合
provide("blocks", blockRefs);

// 注入页面顶层商品ID
provide("topProductId", topProductId);

onMounted(() => {
  const routeNameMap = {
    sale: "consumerGoods", // 消费品
    mro: "industrialGoods", // 工业品
    food: "foodGoods" // 食品
  };
  getUserAuth(routeNameMap[query.type as string]).then(({ code, data }) => {
    if (code == ResultEnum.SUCCESS) {
      auth.value = data;
    }
  });
  init();
});
</script>

<style scoped lang="scss">
.product-card-container {
  display: flex;
  flex-direction: column;
  margin: calc(0px - var(--merak-padding));
  height: calc(100% + var(--merak-padding) * 2);
  color: var(--merak-text-color);
  font-size: var(--merak-text-size);
  background-color: var(--el-bg-color-page);
  & > :not(:first-child) {
    flex: auto;
    margin-top: var(--merak-space);
    min-height: 0;
  }
  .header {
    display: flex;
    color: #646567;
    font-size: 12px;
    padding: var(--merak-space) var(--merak-padding);
    background-color: var(--el-bg-color);
    border-radius: var(--merak-rounded);
    & > :nth-child(2n) {
      margin-left: 50px;
    }
    & > :nth-child(3) {
      margin-left: 78px;
    }
    .item {
      display: flex;
      align-items: center;
      svg {
        margin-right: var(--merak-space);
        width: 20px;
        height: 20px;
      }
    }
  }
  .content {
    :deep(.merak-collapse-item) {
      .merak-collapse-item--body-wrapper {
        padding-left: 28px;
      }
      .merak-collapse-item--header-handler .el-button.is-link {
        margin: 0;
        padding: 0;
        min-width: auto;
      }
      .el-form--label-right .el-form-item {
        align-items: baseline;
        &__label {
          justify-content: flex-end;
          padding-right: 30px;
          line-height: 1.5;
          text-align: right;
        }
      }
    }
  }
}

:global(.el-image-viewer__canvas img) {
  max-height: 80% !important;
}
</style>
